#include "CmdEngine.h"

CmdEngine::CmdEngine(QObject *parent) :
    QObject(parent),
    mScriptEngine(),
    mHolder(LibLoader::getInstance(), &mScriptEngine),
    mThisObj(NULL)
{}

QString CmdEngine::createObject(const QString &clsname, const QVector<Command> &cmds)
{
    QString id;
    foreach ( Command c, cmds ) // find object id
        if ( c.type() == Command::IDASSIGN )
            id = c.args()[0].toString();

    if ( id.isEmpty() )
        id = mHolder.createUniqId();

    mThisObj = mHolder.getObject(id, clsname);

    if ( mThisObj )
        foreach ( Command c, cmds )
            singleCommand(c);
    else
        std::cerr << "\e[1;31mobject '\e[1;33m" << id.toStdString()
                  << "\e[1;31m' of class '\e[1;33m" << clsname.toStdString() << "\e[1;31m' not created\e[m" << endl;

    return id;
}

QObject* CmdEngine::getObjById(const QString &id) { return mHolder.getObject(id); }
QObject* CmdEngine::thisObj() const { return mThisObj; }
void CmdEngine::finish() {
    std::cerr << "\e[1;33mTODO: finishing CmdEngine\e[m" << endl;
    emit finished();
}

void CmdEngine::singleCommand(const Command &cmd)
{
    switch ( cmd.type() )
    {
    case Command::IMPORT:
        import(cmd);
        break;
    case Command::ROOTOBJ:
        break;
    case Command::IDASSIGN: // let the object know it's id
    case Command::ASSIGN:
        assign(cmd);
        break;
    default:
        std::cerr << "TODO: unrecognized command type" << endl;
    }
}

void CmdEngine::import(const Command &cmd)
{
    if ( cmd.args().count() == 1 ) // lib import
    {
        std::cerr << "\e[0;32m trying to load lib: \e[1;32m"
                  << cmd.args()[0].toString().toStdString() << "\e[m" << std::endl;
        LibLoader::getInstance()->loadLib(cmd.args()[0].toString());
    }
    else if ( cmd.args().count() == 2 ) // script import
    {
        std::cerr << "TODO: script import not implenemted" << std::endl;
    }
}

void CmdEngine::assign(const Command &cmd)
{
    if ( mThisObj )
    {
        const char* pname = cmd.args()[0].toString().toStdString().c_str();
        mThisObj->setProperty(pname, cmd.args()[1]);
    }
}

void CmdEngine::rootobj(const Command &cmd)
{
    QObject* root = cmd.args()[0].value< QObject* >();
    QObject::connect(root, SIGNAL(destroyed()), this, SLOT(finish()));
}
